package com.simple.common.entity.req.vm.pay;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import reactor.core.publisher.Flux;

import javax.validation.constraints.Digits;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author yasud
 * @date 2020年09月28日 16:11
 * @description
 */
@Data
public class PayBase extends ReqBase {

    /**
     * 订单编号
     */
    @NotBlank(message = "orderNo is empty")
    private String orderNo;

    /**
     * 订单金额
     */
    @NotBlank(message = "amount  is empty")
    @Digits(integer = 11, fraction = 2, message = "amount format error")
    private String amount;

    /**
     * 支付币种
     */
    @NotBlank(message = "currency is empty")
    private String currency;

    /**
     * 异步回调地址
     */
    @NotBlank(message = "asyncUrl is empty")
//    @Pattern(regexp = "((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]+|(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)[A-Za-z0-9\\.\\-]+)((?:\\/[\\+~%\\/\\.\\w\\-_]*)?\\??(?:[\\-\\+=&;%@\\.\\w_]*)#?(?:[\\.\\!\\/\\\\\\w]*))?)", message = "asyncUrl format error")
    private String asyncUrl;

    /**
     * 其他信息
     * 这里需要校验参数
     */
    private Map<String, Object> extraInfo;

    /**
     * 拓展字段检查
     */
    @Override
    public void check(Consumer<ReqBase>... consumers) {
        Map<String, Object> extra = ObjectUtils.defaultIfNull(getExtraInfo(), Maps.newHashMap());
        Map<String, Consumer<Object>> predicateMapping = predicateMapping();
        predicateMapping.forEach((s, objectConsumer) -> {
            objectConsumer.accept(extra.get(s));
        });
        checkOther();
        if (ArrayUtils.isNotEmpty(consumers)) {
            Flux.fromArray(consumers).subscribe(v -> v.accept(this));
        }
    }

    /**
     * 进行其他检查
     */
    protected void checkOther() {

    }

    /**
     * 默认构造
     *
     * @return
     */
    protected Map<String, Consumer<Object>> predicateMapping() {
        return ImmutableMap.of();
    }

    /**
     * 返回给定的字符串形式
     *
     * @param key
     * @return
     */
    @JsonIgnore
    public String getAsStringFromExtra(String key) {
        return (String) getExtraInfo().get(key);
    }

    /**
     * 返回给定key的 bigdecimal
     *
     * @param key
     * @return
     */
    @JsonIgnore
    public BigDecimal getAsBigDecimalFromExtra(String key) {
        return (BigDecimal) getExtraInfo().get(key);
    }

    /**
     * 返回给定int
     *
     * @param key
     * @return
     */
    @JsonIgnore
    public Integer getAsIntFromExtra(String key) {
        return (Integer) getExtraInfo().get(key);
    }

    /**
     * 给定列表
     *
     * @param key
     * @return
     */
    @JsonIgnore
    public List getAsListFromExtra(String key) {
        return (List) getExtraInfo().get(key);
    }

    /**
     * 给定 map
     *
     * @param key
     * @return
     */
    @JsonIgnore
    public Map getAsMapFromExtra(String key) {
        return (Map) getExtraInfo().get(key);
    }

}
